package com.wei.czz.common.enums.rabbitMQ;

import com.wei.czz.common.dto.common.NameValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2024-11-22 10:42:01
 * className: MqEnum RabbitMQ枚举类
 * version: 1.0
 * description:
 */
@Getter
@AllArgsConstructor
public enum MqEnum {

    // 博客审核
    BLOG_AUDIT(Exchange.BLOG_DIRECT, Queue.BLOG_AUDIT, Queue.BLOG_AUDIT + ".key"),
    // 博客评论
    BLOG_COMMENT(Exchange.BLOG_DIRECT, Queue.BLOG_COMMENT, Queue.BLOG_COMMENT + ".key"),
    // 博客评论点赞
    BLOG_COMMENT_LIKE(Exchange.BLOG_DIRECT, Queue.BLOG_COMMENT_LIKE, Queue.BLOG_COMMENT_LIKE + ".key"),
    // 用户操作博客（点赞、收藏、浏览）
    USER_BLOG_OPT(Exchange.BLOG_DIRECT, Queue.USER_BLOG_OPT, Queue.USER_BLOG_OPT + ".key"),
    // 博客扇形交换机
    BLOG_FANOUT(Exchange.BLOG_FANOUT, StringUtils.EMPTY, StringUtils.EMPTY),
    // 博客标签变化（增加、减少）
    BLOG_TAG(Exchange.BLOG_FANOUT, Queue.BLOG_TAG, StringUtils.EMPTY),
    // 博客状态变化
    BLOG_STATUS(Exchange.BLOG_FANOUT, Queue.BLOG_STATUS, StringUtils.EMPTY),

    // 系统导出任务
    EXPORT_TASK(Exchange.TASK_DIRECT, Queue.EXPORT_TASK, Queue.EXPORT_TASK + ".key"),
    // 系统导入任务
    IMPORT_TASK(Exchange.TASK_DIRECT, Queue.IMPORT_TASK, Queue.IMPORT_TASK + ".key"),

    // 游戏用户
    GAME_USER(Exchange.GAME_DIRECT, Queue.GAME_USER, Queue.GAME_USER + ".key"),
    // 游戏奖品
    GAME_PRIZE(Exchange.GAME_DIRECT, Queue.GAME_PRIZE, Queue.GAME_PRIZE + ".key"),

    // 死信
    DEAD(Exchange.DEAD_DIRECT, Queue.DEAD, Queue.DEAD + ".key"),

    // 角色
    ROLE(Exchange.ROLE_DIRECT, StringUtils.EMPTY, StringUtils.EMPTY),
    // 部门关联角色
    DEPT_ROLE(Exchange.ROLE_DIRECT, Queue.DEPT_ROLE, Queue.DEPT_ROLE + ".key"),
    // 部门关联用户
    DEPT_USER(Exchange.ROLE_DIRECT, Queue.DEPT_USER, Queue.DEPT_USER + ".key"),

    // 角色授权组关联角色变更
    ROLE_SPACE_ROLE(Exchange.ROLE_SPACE_DIRECT, Queue.ROLE_SPACE_ROLE, Queue.ROLE_SPACE_ROLE + ".key"),
    // 角色授权组关联用户变更
    ROLE_SPACE_USER(Exchange.ROLE_SPACE_DIRECT, Queue.ROLE_SPACE_USER, Queue.ROLE_SPACE_USER + ".key"),

    ;

    private static final Logger log = LoggerFactory.getLogger(MqEnum.class);

    /**
     * 交换机
     */
    private final String exchange;

    /**
     * 消息队列
     */
    private final String queue;

    /**
     * 路由键
     */
    private final String routingKey;

    /**
     * 消息队列交换机
     */
    public static class Exchange {

        /**
         * 博客-直连交换机
         */
        public static final String BLOG_DIRECT = "blog.direct";

        /**
         * 博客-扇出交换机
         */
        public static final String BLOG_FANOUT = "blog.fanout";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 系统导出/上传任务-直连交换机
         */
        public static final String TASK_DIRECT = "task.direct";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 游戏奖品/用户修改-直连交换机
         */
        public static final String GAME_DIRECT = "game.direct";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 死信-直连交换机
         */
        public static final String DEAD_DIRECT = "czz.dead.exchange";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 用户关联角色-扇出交换机
         */
        public static final String USER_ROLE_FANOUT = "czz.user_role_change.fanout";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 角色授权组-直连交换机
         */
        public static final String ROLE_SPACE_DIRECT = "role_space.direct";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 角色-直连交换机
         */
        public static final String ROLE_DIRECT = "role.direct";

        /**
         * 角色-扇出交换机
         */
//        public static final String ROLE_FANOUT = "role.fanout";

        /*------------------------------------------------------------------------------------------------------------*/
    }

    /**
     * 消息队列常量类
     */
    public static class Queue {

        /**
         * 博客审核-消息队列
         */
        public static final String BLOG_AUDIT = "blog.audit";

        /**
         * 博客评论-消息队列
         */
        public static final String BLOG_COMMENT = "blog.comment";

        /**
         * 博客评论点赞-消息队列
         */
        public static final String BLOG_COMMENT_LIKE = "blog.comment.like";

        /**
         * 用户操作博客-消息队列
         */
        public static final String USER_BLOG_OPT = "user.blog.opt";

        /**
         * 博客关联标签数量变化-消息队列
         */
        public static final String BLOG_TAG = "blog.tag";

        /**
         * 博客状态变化-消息队列
         */
        public static final String BLOG_STATUS = "blog.status";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 系统导出任务-消息队列
         */
        public static final String EXPORT_TASK = "export.task";

        /**
         * 系统上传任务-消息队列
         */
        public static final String IMPORT_TASK = "import.task";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 游戏用户剩余次数修改-消息队列
         */
        public static final String GAME_USER = "game.user";

        /**
         * 游戏奖品剩余数量修改-消息队列
         */
        public static final String GAME_PRIZE = "game.prize";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 死信-消息队列
         */
        public static final String DEAD = "czz.dead";

        /*------------------------------------------------------------------------------------------------------------*/

        /**
         * 博客审核分组用户变更-消息队列
         */
        public static final String BLOG_AUDIT_GROUP_USER_MODIFY = "user.role.change";

        /*------------------------------------------------------------------------------------------------------------*/

        /*
            部门关联角色变更-消息队列
         */
        public static final String DEPT_ROLE = "dept.role";

        /*
            部门用户关联角色变更-消息队列
         */
        public static final String DEPT_USER = "dept.user";

        /**
         * 角色授权组关联角色变更-消息队列
         */
        public static final String ROLE_SPACE_ROLE = "role.space.role";

        /**
         * 角色授权组关联用户变更-消息队列
         */
        public static final String ROLE_SPACE_USER = "role.space.user";

        /*------------------------------------------------------------------------------------------------------------*/

    }

    /**
     * 获取交换机枚举列表
     * @return 列表
     */
    public static List<NameValue<String>> getExchangeList() {
        return getList(Exchange.class);
    }

    /**
     * 获取交换机枚举列表
     * @return 列表
     */
    public static List<NameValue<String>> getExchangeList(String queue) {
        return Stream.of(values())
                .filter(mqEnum -> Objects.equals(mqEnum.getQueue(), queue))
                .map(mqEnum -> new NameValue<>(mqEnum.getExchange(), mqEnum.getExchange()))
                .collect(Collectors.toList());
    }

    /**
     * 获取交换机枚举列表
     * @return 列表
     */
    public static List<MqEnum> findExchangeList(String exchange) {
        return Stream.of(values())
                .filter(mqEnum -> Objects.equals(mqEnum.getExchange(), exchange))
                .collect(Collectors.toList());
    }

    /**
     * 获取消息队列枚举列表
     * @return 列表
     */
    public static List<NameValue<String>> getQueueList() {
        return getList(Queue.class);
    }

    /**
     * 获取消息队列枚举列表
     * @param exchange 交换机
     * @return 列表
     */
    public static List<NameValue<String>> getQueueList(String exchange) {
        return Stream.of(values())
                .filter(mqEnum -> Objects.equals(mqEnum.getExchange(), exchange))
                .filter(mqEnum -> StringUtils.isNotBlank(mqEnum.getQueue()))
                .map(mqEnum -> new NameValue<>(mqEnum.getQueue(), mqEnum.getQueue()))
                .collect(Collectors.toList());
    }

    /**
     * 获取枚举列表
     * @param clazz 泛型类的class对象
     * @return 列表
     * @param <T> 泛型
     */
    private static <T> List<NameValue<String>> getList(Class<T> clazz) {
        return Stream.of(clazz.getDeclaredFields())
                .filter(field -> Modifier.isStatic(field.getModifiers()))
                .map(field -> {
                    field.setAccessible(true);
                    try {
                        // 入参传空，表示获取静态字段
                        return field.get(null);
                    } catch (IllegalAccessException e) {
                        log.error("获取静态字段值异常。className={} name={} message={}", clazz.getSimpleName(),
                                field.getName(), e.getMessage(), e);
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .filter(value -> value instanceof String)
                .map(value -> {
                    String val = (String) value;
                    return new NameValue<>(val, val);
                })
                .collect(Collectors.toList());
    }

}
